#include "SearchField.h"
#include "../../core/Impp.h"

namespace Impp
{


BEGIN_EVENT_TABLE(SearchField, wxTextCtrl)
  EVT_TEXT(wxID_ANY,SearchField::onTextedChanged)
  EVT_KILL_FOCUS(SearchField::onKillFocus)
  EVT_KEY_DOWN(SearchField::onKeyDown)
END_EVENT_TABLE()

;

SearchField::SearchField(BuddyList* list, wxWindow *parent, wxWindowID id) :
	wxTextCtrl(parent, id, wxEmptyString, wxDefaultPosition, wxDefaultSize, wxPROCESS_ENTER),
	list(list),
	results(NULL)
{
	Hide();
}


void SearchField::trigger(const wxChar & c){
	if(results == NULL){
		results = new SearchResults(this);
	}

	if(!IsShown()){
		Show(true);
	}
	SetFocus();
	SetFocusFromKbd();

	WriteText(wxString(wxT(""))<<c);
}

void SearchField::hideSearchField(){
	SetValue(wxT(""));
	list->hideSearchField();
	results->Hide();
}

void SearchField::onKillFocus(wxFocusEvent & event){
	if(results == NULL || results->hideSearchField){
		hideSearchField();
	}
	event.Skip();
}

void SearchField::onKeyDown(wxKeyEvent & event){
	switch (event.GetKeyCode()) {
		case WXK_UP:
			results->up();
			break;
		case WXK_DOWN:
			results->down();
			break;
		case WXK_ESCAPE:
			hideSearchField();
			break;
		case WXK_RETURN:
			results->enter();
			break;
		default:
			break;
	}
	event.Skip();
}

void SearchField::onTextedChanged(wxCommandEvent & event){

	std::vector<Buddy*> buddies = Impp::exemplar()->getAllBuddies();
	std::vector<Buddy*> found;

	wxString search = GetValue().Lower();

	for (size_t i = 0; i < buddies.size(); ++i) {
		if(wxNOT_FOUND != buddies[i]->getName().Lower().Find(search)){
			found.push_back(buddies[i]);
		}
	}


	wxPoint screenPos = list->getTreeList()->GetScreenPosition();
	wxSize size = list->getTreeList()->GetSize();


	wxRect screenRect = ::wxGetClientDisplayRect();

	//Ok Default we are displaying the results on the right of the buddylist
	wxPoint displayPos = wxPoint(screenPos.x+size.x,screenPos.y);

	//if there isnt room -> diyplay it on the left side
	if(displayPos.x+220 >= screenRect.x+screenRect.width){
		displayPos.x = screenPos.x-200;
	}

	//ok there is no room too, maximized? so display it as far as possible on
	//the right
	if(displayPos.x < screenRect.x){
		displayPos.x = screenRect.x+screenRect.width-200;
	}

	//in Windows the popup takes the elativ position of its parent not the absolute screen pos
	//so fix this here:
	#ifdef __WXMSW__
		displayPos = displayPos-GetScreenPosition();
	#endif

	if(results->GetPosition() != displayPos){
		results->SetPosition(displayPos);
	}


	results->setData(found);


	if(!results->IsShown()){
		results->Show();
	}
}

SearchField::~SearchField()
{

}


BEGIN_EVENT_TABLE(SearchResults, ImppPopupWindow)
	EVT_LISTBOX_DCLICK(wxID_ANY, SearchResults::onItemActivated)
END_EVENT_TABLE()
;

SearchResults::SearchResults(SearchField *parent) :
	ImppPopupWindow(parent),sf(parent),hideSearchField(true)
{
	list = new wxListBox(this,wxID_ANY);
	list->Connect(wxEVT_RIGHT_UP,wxMouseEventHandler(SearchResults::onRightClicked),NULL,this);
	SetPosition(wxPoint(-200,-200));
	Layout();
}

SearchResults::~SearchResults(){

}

void SearchResults::setData(const std::vector<Buddy*> & buddies){

	list->Clear();
	this->buddies=buddies;

	for (size_t i = 0; i < buddies.size(); ++i) {
		list->Insert(buddies[i]->getName(),i);
	}

	#ifdef __WXMSW__
		wxCoord itemHight = 20;
	#else
		wxCoord itemHight = 27;
	#endif

	wxSize size(200,itemHight*buddies.size());

	if(size.y> 400){
		size.y = 400;
	}

	SetSize(size);
	list->SetSize(size);


	if(!buddies.empty()){
		list->SetSelection(0);
	}


}

void SearchResults::onItemActivated(wxCommandEvent & event){
	iChatWindow* chatWin = Impp::exemplar()->getModuleManager()->getChatWindowModule();
	if(chatWin != NULL){
		chatWin->showChatWindow(buddies[event.GetInt()]);
	}else{
		wxLogDebug(wxT("SearchResults::onItemActivated: No Chatwindow that can be showen!"));
	}
	sf->hideSearchField();
}

void SearchResults::onRightClicked(wxMouseEvent & event){
	int id = list->HitTest(event.GetPosition());
	if(id!=wxNOT_FOUND){
		hideSearchField = false;

		iUserInterface* ui = Impp::exemplar()->getModuleManager()->getUserInterfaceModule();
		if(ui != NULL){
			wxMenu menu;
			ui->buildBuddyMenu(&menu, buddies[id]);
			wxPoint pos = event.GetPosition();
			pos.x=GetSize().x;
			list->PopupMenu(&menu,pos);
		}else{
			wxLogDebug(wxT("BuddyTreeList::onMouseDown: No UserInterface found!"));
		}

		hideSearchField = true;
		sf->hideSearchField();
	}
}

void SearchResults::up(){
	int selected = list->GetSelection();
	if(selected != 0){
		list->SetSelection(selected-1);
	}
}

void SearchResults::down(){
	int selected = list->GetSelection();
	if(selected != (int)buddies.size()-1){
		list->SetSelection(selected+1);
	}
}

void SearchResults::enter(){
	int selected = list->GetSelection();

	if(selected != wxNOT_FOUND){
		iChatWindow* chatWin = Impp::exemplar()->getModuleManager()->getChatWindowModule();
		if(chatWin != NULL){
			chatWin->showChatWindow(buddies[selected]);
		}else{
			wxLogDebug(wxT("SearchResults::enter: No Chatwindow that can be showen!"));
		}
		sf->hideSearchField();
	}else{
		sf->hideSearchField();
	}
}


}
